home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / RGASM.RAR / ASMCODE.EXE / CHAPT12 / QSOUND.ASM < prev    next >
Encoding:
Assembly Source File  |  1994-08-28  |  4.4 KB  |  87 lines

  1. ;
  2. ;       Program QSound ( Chapter 12 )
  3. ;
  4.     page    55,132
  5. .model  medium,BASIC
  6. ;===    This generates the statement PROTO for MASM 6 or PUBLIC for others
  7.     IFDEF ??VERSION
  8. public  QSound  
  9.     ELSEIF @version EQ 600
  10. QSound  PROTO    BASIC freq: PTR WORD, durat: PTR WORD
  11.     ELSE
  12. public  QSound
  13.     ENDIF   
  14. ;===    Data segments   
  15. .data                   
  16. Nticks  dw      0                       ; number of ticks for delaying
  17. ;===    Code segment
  18. .code
  19. QSound  PROC    BASIC uses ax bx cx dx es di, freq: PTR WORD, durat: PTR WORD
  20. ;===    accept the parameter DURAT (sound duration)
  21.     mov     ax,5000                 ; default value for DURAT is 5 seconds
  22.     mov     bx,durat                ; address of DURAT into ES:BX
  23.     mov     bx,[bx]                 ; value of DURAT into BX register
  24.     cmp     bx,0                    ; compare DURAT to 0
  25.     je      Accept                  ; skip illegal value of DURAT
  26.     cmp     ax,5000                 ; compare DURAT to 5000
  27.     jg      Accept                  ; skip illegal value of DURAT
  28.     mov     ax,bx                   ; load DURAT into AX
  29. ;===    convert DURAT value into timer ticks ( Tics = Msecs * 91 / 5000)
  30. Accept: mov     Nticks,ax               ; save value of DURAT in memory
  31. ;===    modify the latch of the timer channel 0 (10 times faster)       
  32.     mov     al,00110110b
  33.     out     43h,al
  34.     mov     ax,1193                 ; latch value - 1/10 of generator freq.
  35.     out     40h,al                  ; send low byte of latch value
  36.     mov     al,ah                   ; prepare for sending high byte 
  37.     out     40h,al                  ; send high byte of latch value
  38. ;===    accept the parameter FREQ (sound frequency)
  39.     mov     bx,freq                 ; address of frequency into ES:BX
  40.     mov     di,[bx]                 ; value of frequency into DI
  41.     cmp     di,0                    ; is zero frequency reqested?
  42.     jg      Sound                   ; if not, generate sound
  43. ;===    zero frequency - disable sound  
  44.     in      al,61h                  ; read speaker port content
  45.     and     al, not 00000011b       ; set bits 0 and 1 of port 61h to 1     
  46.     out     61h,al                  ; turn speaker off
  47.     jmp     ToTicks                 ; wait for time defined by DURAT
  48. ;===    program channel 2 of Programmable Timer for sound generation    
  49. Sound:  mov     al,10110110b            ; channel 2, write lsb/msb,
  50.     out     43h,al                  ; operation mode 3, binary
  51.     mov     dx,12h                  ; store 12 34DCh (1 193 180) into
  52.     mov     ax,34dch                ; DX:AX for DIV command (dividend)
  53.     div     di                      ; obtain frequency divisor
  54.     out     42h,al                  ; send low byte of divisor
  55.     mov     al,ah                   ; prepare for sending high byte
  56.     out     42h,al                  ; send high byte of divisor
  57. ;===    turn the sound on       
  58.     in      al,61h                  ; read speaker port content
  59.     or      al,00000011b            ; set bits 0 and 1 of port 61h to 1
  60.     out     61h,al                  ; turn speaker on
  61. ;===    get current time (the number of ticks since midnight)
  62. ToTicks:mov     ax,40h                  ; address of BIOS data segment into AX 
  63.     mov     es,ax                   ; ES will point to BIOS data segment
  64. ;===    calculate the moment of turning the sound off           
  65.     mov     bx,es:[6Ch]             ; low part of ticks number into BX
  66.     add     bx,Nticks               ; add DURAT to that low part value
  67.     mov     dx,es:[6Eh]             ; save high part of ticks number
  68. ;===    wait for the obtained number of ticks defined by the DURAT parameter    
  69. Delay:  cmp     es:[6Eh],dx             ; Is high part of time counter right?
  70.     jb      Delay                   ; if not, continue to wait
  71.     cmp     es:[6Ch],bx             ; has time gone?        
  72.     jb      Delay                   ; if not, continue to wait
  73. ;==     turn the speaker off    
  74. IsTime: in      al,61h                  ; read speaker port contens
  75.     and     al, not 00000011b       ; set bits 0 and 1 of port 61h to 1     
  76.     out     61h,al                  ; turn speaker off
  77. ;===    restore the latch of the timer channel 0 (default value is 0FFFFh)
  78.     mov     al,00110110b
  79.     out     43h,al
  80.     mov     al,0FFh                 ; this is low byte of value 65535
  81.     out     40h,al                  ; send low byte of latch value (65535)
  82.     out     40h,al                  ; send high byte of latch value (65535)
  83. ;===    return to caller                
  84.     ret
  85. QSound  endp
  86.     end
  87.